import {EChartOption} from "echarts";
import {mixedOpt} from "..";

export namespace BaseOption {}

export class BaseOption {
    private axis: EChartOption.BasicComponents.CartesianAxis = {};
    private seriesMap: Map<string, EChartOption.Series> = new Map();
    private _yAxis: EChartOption.YAxis = {};
    private _xAxis: EChartOption.XAxis = {};
    private _opt: EChartOption = {};
    private legend: EChartOption.Legend = {
        itemWidth: 10,
        itemHeight: 10,
        icon: "rect",
    };
    private grid: EChartOption.Grid = {
        containLabel: true,
    };

    private get yAxis(): EChartOption.YAxis {
        return mixedOpt(this.axis, this._yAxis);
    }

    private get xAxis(): EChartOption.XAxis {
        return mixedOpt(this.axis, this._xAxis);
    }

    private get opt(): EChartOption {
        return mixedOpt({
            xAxis: this.getXAxis(),
            yAxis: this.getYAxis(),
            legend: this.getLegend(),
            grid: this.getGrid(),
        }, this._opt);
    }

    public setAxis(axis: EChartOption.BasicComponents.CartesianAxis): this {
        this.axis = axis;
        return this;
    }

    public getAxis(): EChartOption.BasicComponents.CartesianAxis {
        return this.axis;
    }

    public setYAxis(yAxis: EChartOption.YAxis): this {
        this._yAxis = yAxis;
        return this;
    }

    public getYAxis(): EChartOption.YAxis {
        return this.yAxis;
    }

    public seXAxis(xAxis: EChartOption.XAxis): this {
        this._xAxis = xAxis;
        return this;
    }

    public getXAxis(): EChartOption.XAxis {
        return this.xAxis;
    }

    public setLegend(legend: EChartOption.Legend): this {
        this.legend = legend;
        return this;
    }

    public getLegend(): EChartOption.Legend {
        return this.legend;
    }

    public setGrid(grid: EChartOption.Grid): this {
        this.grid = grid;
        return this;
    }

    public getGrid(): EChartOption.Grid {
        return this.grid;
    }

    public setOpt(opt: EChartOption): this {
        this._opt = opt;
        return this;
    }

    public getOpt() {
        return this.opt;
    }

    public setSeriesOpt(seriesType: string, opt: EChartOption.Series): this {
        this.seriesMap.set(seriesType, opt);
        return this;
    }

    public getSeriesOpt(seriesType: string): EChartOption.Series | undefined {
        return this.seriesMap.get(seriesType);
    }

    public mixedSeries(series: EChartOption.Series): EChartOption.Series {
        if (!series.type) {
            series.type = "line";
        }
        if (this.seriesMap.has(series.type)) {
            return mixedOpt(this.getSeriesOpt(series.type), series);
        }
        return series;
    }

    public mixOpt<T>(opt: EChartOption<T>): EChartOption<T> {
        const newOpt = mixedOpt(this.getOpt(), opt);
        if (newOpt.xAxis instanceof Array) {
            newOpt.xAxis = newOpt.xAxis.map((item) => {
               return mixedOpt(this.getXAxis(), item);
            });
        }
        if (newOpt.yAxis instanceof Array) {
            newOpt.yAxis = newOpt.yAxis.map((item) => {
               return mixedOpt(this.getYAxis(), item);
            });
        }
        if (newOpt.series instanceof Array) {
            (newOpt.series as EChartOption.Series[]) = newOpt.series.map((seriesOne) => {
               return this.mixedSeries(seriesOne);
            });
        }
        return newOpt;
    }
}
